package com.aliyun.gts.sso.domain;

import com.aliyun.gts.sso.constant.SFSSOLoginConstants;
import lombok.Data;

import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Created by 鸿度 on 2024-06-18 14:00.
 */
@Data
public class CookieDTO {

    public static final String DEFAULT_COOKIE_PATH = "/";

    protected static final String ANCIENT_DATE;

    protected static final ThreadLocal<DateFormat> COOKIE_DATE_FORMAT =
            ThreadLocal.withInitial(() -> {
                DateFormat df =
                        new SimpleDateFormat(SFSSOLoginConstants.COOKIE_DATE_PATTERN, Locale.US);
                df.setTimeZone(TimeZone.getTimeZone("GMT"));
                return df;
            });

    static {
        ANCIENT_DATE = COOKIE_DATE_FORMAT.get().format(new Date(10000));
    }

    private String name;
    private String value;
    private String domain;
    private String path = DEFAULT_COOKIE_PATH;
    private Integer maxAge;
    private boolean httpOnly;
    private boolean secure;
    private String sameSite;

    public String toString() {
        return generateCookieHeader();
    }

    public String generateCookieHeader() {
        StringBuffer cookieHeaderBuff = new StringBuffer();
        cookieHeaderBuff.append(name)
                .append("=")
                .append(value);
        if (maxAge != null) {
            if (maxAge > -1) {
                // Negative Max-Age is equivalent to no Max-Age
                cookieHeaderBuff.append("; Max-Age=");
                cookieHeaderBuff.append(maxAge);
                // Microsoft IE and Microsoft Edge don't understand Max-Age so send
                // expires as well. Without this, persistent cookies fail with those
                // browsers. See http://tomcat.markmail.org/thread/g6sipbofsjossacn
                // Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
                cookieHeaderBuff.append("; Expires=");
                // To expire immediately we need to set the time in past
                if (maxAge == 0) {
                    cookieHeaderBuff.append(ANCIENT_DATE);
                } else {
                    COOKIE_DATE_FORMAT.get().format(
                            new Date(System.currentTimeMillis() + maxAge * 1000L),
                            cookieHeaderBuff,
                            new FieldPosition(0));
                }
            }
        }
        cookieHeaderBuff.append("; Domain=").append(domain);
        cookieHeaderBuff.append("; Path=").append(path);
        if (secure && sameSite != null && !"".equals(sameSite)) {
            cookieHeaderBuff.append("; SameSite=").append(sameSite);
        }
        if (secure) {
            cookieHeaderBuff.append("; Secure");
        }
        if (httpOnly) {
            cookieHeaderBuff.append("; HttpOnly");
        }
        return cookieHeaderBuff.toString();
    }
}
